package com.zmc.order.listener;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.zmc.common.domain.resp.order.ThirdPayResp;
import com.zmc.order.application.OrderApplicationService;
import com.zmc.common.constant.QueueConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @Author：zmc
 * @Date：2024/12/17 22:19
 */

@Component
public class OrderQueueConsumer {

    public static final Logger log = LoggerFactory.getLogger(OrderQueueConsumer.class);

    @Autowired
    private OrderApplicationService orderApplicationService;

    /**
     * 延时关单
     * */
    @RabbitListener(queues = QueueConstant.ORDER_DEAD_LETTER_QUEUE)
    @RabbitHandler
    public void closeOrder(String orderSn, Message message, Channel channel) throws IOException {
        long msgTag = message.getMessageProperties().getDeliveryTag();
        log.info("延时关闭订单mq，接收到消息：orderSn:{}, msgTag:{}", orderSn, msgTag);
        //关闭订单
        orderApplicationService.cancelOrder(orderSn);
        /*
         * 用于确认已经接收并处理了消息。
         * long deliveryTag: 消息的唯一标识。每条消息都有自己的ID号，用于标识该消息在channel中的顺序。当消费者接收到消息后，需要调用channel.basicAck方法并传递deliveryTag来确认消息的处理。
         * boolean multiple 是否批量确认消息，当传false时，只确认当前 deliveryTag对应的消息;当传true时，会确认当前及之前所有未确认的消息。
         * */
        channel.basicAck(msgTag, false);
    }

    /**
     * 分单
     * */
    @RabbitListener(queues = QueueConstant.SPLIT_ORDER_QUEUE)
    @RabbitHandler
    public void splitOrder(ThirdPayResp payResp, Message message, Channel channel) throws IOException {
        long msgTag = message.getMessageProperties().getDeliveryTag();
        log.info("分单mq，接收到消息:{}, msgTag:{}", JSON.toJSONString(payResp), msgTag);
        //分单
        orderApplicationService.splitOrder(payResp);
        channel.basicAck(msgTag, false);
    }

    /**
     * 退款
     * */
    @RabbitListener(queues = QueueConstant.REFUND_QUEUE)
    @RabbitHandler
    public void refund(String orderSn, Message message, Channel channel) throws IOException {
        long msgTag = message.getMessageProperties().getDeliveryTag();
        log.info("退款mq，接收到消息,orderSn : {}, msgTag:{}", orderSn,  msgTag);
        orderApplicationService.refundHandle(orderSn);
        channel.basicAck(msgTag, false);
    }
}
